package com.stefanini.pe.bbva.bp.in.bo.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.pe.bbva.utils.Constantes;
import com.stefanini.pe.bbva.bp.in.bo.iface.CalculadoraModBOIface;

import com.stefanini.pe.bbva.bp.in.dao.iface.CalculadoraDAOIface;
import com.stefanini.pe.bbva.bp.in.dao.iface.CalculadoraModDAOIface;
import com.stefanini.pe.bbva.bp.in.to.FactorTipoCambio;
import com.stefanini.pe.bbva.bp.in.to.MontoCalculadoraTO;
import com.stefanini.pe.bbva.bp.in.to.PosicionRebalanceoTO;
import com.stefanini.pe.bbva.bp.in.to.RebalanceoTO;
import com.stefanini.pe.bbva.bp.in.utils.Util;

@Service(value="calculadoraModBO")
public class CalculadoraModBOImpl implements CalculadoraModBOIface {
	@Autowired
	@Qualifier("calculadoraModDAO")
	private CalculadoraModDAOIface calculadoraModDAOIface;
	@Autowired
	private CalculadoraDAOIface calculadoraDaoIface;
	
	private String idrebalanceo=null;
	List<Map<String,Object>> listaDistribucionCalEdion=null;
	
	public List<Map<String, Object>> listarDetalleDistribucion(String codCliente,String codContratos){
		int i=0;
		List<Map<String,Object>> listaDistribucion=calculadoraModDAOIface.listarCalculadora(codCliente, codContratos);
		List<Map<String, Object>> listaPadre=new ArrayList<Map<String,Object>>();
		
		if(listaDistribucion.size()>0){
			List<RebalanceoTO> sublista=new ArrayList<RebalanceoTO>();
			RebalanceoTO reba=new RebalanceoTO();
			RebalanceoTO pie=new RebalanceoTO();
			String idCatProducto=Util.nvl(listaDistribucion.get(0).get("idcategoriaporproducto")).toString();		
			for(Map<String, Object> x:listaDistribucion){
				if(!x.get("idcategoriaporproducto").equals(idCatProducto)){
					idCatProducto=Util.nvl(x.get("idcategoriaporproducto")).toString();
					//agregar pie
					Map<String,Object> item=new HashMap<String, Object>();
					item.put("detalle", sublista);
					item.put("pie", pie);
					listaPadre.add(item);
					sublista=new ArrayList<RebalanceoTO>();
					pie=new RebalanceoTO();
				}
				reba=new RebalanceoTO();
				//reba.setFila(i++);
				reba.setDescripcion(Util.nvl(x.get("descripcion")).toString());
				reba.setMoneda(Util.nvl(x.get("moneda")).toString());
				reba.setPeso(Util.big(Util.nvl(x.get("peso")).toString()));
				reba.setPesoFamilia(big(Util.nvl(x.get("pesofamilia")).toString()));
				reba.setPlazo(Util.nvl(x.get("descripcionplazo")).toString());
				reba.setSaldoActual(Util.nvl(x.get("saldoactual")).toString());
				reba.setSaldoRentenido(Util.big(Util.nvl(x.get("saldoretenido")).toString()));
				if(reba.getSaldoRentenido().doubleValue()>0){
					reba.setIndRetencion(Constantes.INDICADOR_RETENCION);
				}
				reba.setSaldoResultante(Util.big(Util.nvl(x.get("saldoresultante")).toString()));
				reba.setCodCatActivo(Util.nvl(x.get("idcategoriaactivo")).toString());
				reba.setCodCatProd(Util.nvl(x.get("idcategoriaporproducto")).toString());
				reba.setCodProd(Util.nvl(x.get("codproducto")).toString());
				reba.setCodSubProd(Util.nvl(x.get("codsubproducto")).toString());
				
				if(Util.nvl(x.get("rentabilidad")).toString().length()>0&&!Util.nvl(x.get("rentabilidad")).toString().equals("0")){
					String g=Util.formatDoubleSinComa(Double.valueOf(Util.nvl(x.get("rentabilidad")).toString()));
					reba.setRentabilidad(g);
				}	

				sublista.add(reba);
				
				pie.setDescripcion(Util.nvl(x.get("descripciontotal")).toString());
				pie.setSaldoActual(Util.nvl(x.get("saldoactualtotal")).toString());
				pie.setPeso(Util.big(Util.nvl(x.get("pesototal")).toString()));			
			}
			Map<String,Object> item=new HashMap<String, Object>();
			item.put("detalle", sublista);
			item.put("pie", pie);
			listaPadre.add(item);
		}	
		return listaPadre;
	}
	
	public List<Map<String, Object>> listarDetalleDistribucionModificar(String codCliente,String codContratos,String idrebalanceo){
		int i=0;
		List<Map<String,Object>> listaDistribucion=calculadoraModDAOIface.listarCalculadora(codCliente, codContratos);
		List<Map<String, Object>> listaPadre=new ArrayList<Map<String,Object>>();
		
		listaDistribucionCalEdion=calculadoraModDAOIface.listarDistribucionCalcEdicion(idrebalanceo);
		
		if(listaDistribucion.size()>0){
			List<RebalanceoTO> sublista=new ArrayList<RebalanceoTO>();
			RebalanceoTO reba=new RebalanceoTO();
			RebalanceoTO pie=new RebalanceoTO();
			String idCatProducto=Util.nvl(listaDistribucion.get(0).get("idcategoriaporproducto")).toString();		
			for(Map<String, Object> x:listaDistribucion){
				if(!x.get("idcategoriaporproducto").equals(idCatProducto)){
					idCatProducto=Util.nvl(x.get("idcategoriaporproducto")).toString();
					//agregar pie
					Map<String,Object> item=new HashMap<String, Object>();
					item.put("detalle", sublista);
					item.put("pie", pie);
					listaPadre.add(item);
					sublista=new ArrayList<RebalanceoTO>();
					pie=new RebalanceoTO();
				}
				reba=new RebalanceoTO();
				//reba.setFila(i++);
				reba.setDescripcion(Util.nvl(x.get("descripcion")).toString());
				reba.setMoneda(Util.nvl(x.get("moneda")).toString());
				reba.setPeso(Util.big(Util.nvl(x.get("peso")).toString()));
				reba.setPesoFamilia(big(Util.nvl(x.get("pesofamilia")).toString()));
				reba.setPlazo(Util.nvl(x.get("descripcionplazo")).toString());
				reba.setSaldoActual(Util.nvl(x.get("saldoactual")).toString());
				reba.setSaldoRentenido(Util.big(Util.nvl(x.get("saldoretenido")).toString()));
				if(reba.getSaldoRentenido().doubleValue()>0){
					reba.setIndRetencion(Constantes.INDICADOR_RETENCION);
				}
				reba.setSaldoResultante(Util.big(Util.nvl(x.get("saldoresultante")).toString()));
				reba.setCodCatActivo(Util.nvl(x.get("idcategoriaactivo")).toString());
				reba.setCodCatProd(Util.nvl(x.get("idcategoriaporproducto")).toString());
				reba.setCodProd(Util.nvl(x.get("codproducto")).toString());
				reba.setCodSubProd(Util.nvl(x.get("codsubproducto")).toString());
				
				if(Util.nvl(x.get("rentabilidad")).toString().length()>0&&!Util.nvl(x.get("rentabilidad")).toString().equals("0")){
					String g=Util.formatDoubleSinComa(Double.valueOf(Util.nvl(x.get("rentabilidad")).toString()));
					reba.setRentabilidad(g);
				}	
					
				//Asignar valores de rebalanceo
				if(listaDistribucionCalEdion!=null && listaDistribucionCalEdion.size()>0){
					if (reba.getCodCatProd().trim().equals("4")){
						for(Map<String, Object> y:listaDistribucionCalEdion){
							if(y.get("idcategoriaproducto")!=null && y.get("moneda")!=null){
								if(reba.getCodCatProd().trim().equals(Util.nvl(y.get("idcategoriaproducto").toString().trim()))&&
									reba.getCodProd().trim().equals(Util.nvl(y.get("codproducto")).toString().trim())&& 
									reba.getCodSubProd().trim().equals(Util.nvl(y.get("codsubproducto")).toString().trim())&&
									reba.getMoneda().trim().equals(Util.nvl(y.get("moneda").toString().trim()))&&
									"B".equals(Util.nvl(y.get("tipo").toString().trim()))){
									
									if (!Util.nvlNumber(y.get("rentabilidad")).toString().equalsIgnoreCase("0"))
									{
										reba.setRentabilidad(Util.formatDouble(Double.parseDouble(Util.nvlNumber(y.get("rentabilidad")).toString())));	
									}
									
									if (!Util.nvlNumber(y.get("rentabilidadestimada")).toString().equalsIgnoreCase("0"))
									{
										reba.setRentabilidadEstimada(Util.formatDouble(Double.parseDouble(Util.nvlNumber(y.get("rentabilidadestimada")).toString())));	
									}
									
									if (!Util.nvlNumber(y.get("calculadorapen")).toString().equalsIgnoreCase("0"))
									{
										reba.setSaldoInputPEN(Util.formatDouble(Double.parseDouble(Util.nvlNumber(y.get("calculadorapen")).toString())));//abarrios
									}else if(!Util.nvlNumber(y.get("calculadorausd")).toString().equalsIgnoreCase("0"))
									{
										reba.setSaldoInputUSD(Util.formatDouble(Double.parseDouble(Util.nvlNumber(y.get("calculadorausd")).toString())));//abarrios
									}else if (!Util.nvlNumber(y.get("calculadoraeur")).toString().equalsIgnoreCase("0"))
									{
										reba.setSaldoInputEUR(Util.formatDouble(Double.parseDouble(Util.nvlNumber(y.get("calculadoraeur")).toString())));//abarrios
									}
								}
							}
						}
					}else{
						for(Map<String, Object> y:listaDistribucionCalEdion){
							if(y.get("idcategoriaactivo")!=null && y.get("idcategoriaproducto")!=null && y.get("moneda")!=null){
								if(reba.getCodCatActivo().trim().equals(Util.nvl(y.get("idcategoriaactivo")).toString().trim())&& 
									reba.getCodCatProd().trim().equals(Util.nvl(y.get("idcategoriaproducto").toString().trim()))&&
									reba.getMoneda().trim().equals(Util.nvl(y.get("moneda").toString().trim()))&&
									"B".equals(Util.nvl(y.get("tipo").toString().trim()))){
									
									if (!Util.nvlNumber(y.get("rentabilidad")).toString().equalsIgnoreCase("0"))
									{
										reba.setRentabilidad(Util.formatDouble(Double.parseDouble(Util.nvlNumber(y.get("rentabilidad")).toString())));	
									}
									
									if (!Util.nvlNumber(y.get("rentabilidadestimada")).toString().equalsIgnoreCase("0"))
									{
										reba.setRentabilidadEstimada(Util.formatDouble(Double.parseDouble(Util.nvlNumber(y.get("rentabilidadestimada")).toString())));	
									}

									if (!Util.nvlNumber(y.get("calculadorapen")).toString().equalsIgnoreCase("0"))
									{
										reba.setSaldoInputPEN(Util.formatDouble(Double.parseDouble(Util.nvlNumber(y.get("calculadorapen")).toString())));//abarrios
									}else if(!Util.nvlNumber(y.get("calculadorausd")).toString().equalsIgnoreCase("0"))
									{
										reba.setSaldoInputUSD(Util.formatDouble(Double.parseDouble(Util.nvlNumber(y.get("calculadorausd")).toString())));//abarrios
									}else if (!Util.nvlNumber(y.get("calculadoraeur")).toString().equalsIgnoreCase("0"))
									{
										reba.setSaldoInputEUR(Util.formatDouble(Double.parseDouble(Util.nvlNumber(y.get("calculadoraeur")).toString())));//abarrios
									}
								}
							}
						}
					}
				}
			
				sublista.add(reba);
				
				pie.setDescripcion(Util.nvl(x.get("descripciontotal")).toString());
				pie.setSaldoActual(Util.nvl(x.get("saldoactualtotal")).toString());
				pie.setPeso(Util.big(Util.nvl(x.get("pesototal")).toString()));		
			}
			
			Map<String,Object> item=new HashMap<String, Object>();
			item.put("detalle", sublista);
			item.put("pie", pie);
			listaPadre.add(item);
		}	
		return listaPadre;
	}
	
	public List<PosicionRebalanceoTO> listarMonedasPosicionRebalanceo(){
		List<PosicionRebalanceoTO> lista=new ArrayList<PosicionRebalanceoTO>();
		PosicionRebalanceoTO 
		posiActual=new PosicionRebalanceoTO();
		posiActual.setMoneda(Constantes.CONSTANTE_TIPO_MONEDA_PEN);
		lista.add(posiActual);
		posiActual=new PosicionRebalanceoTO();
		posiActual.setMoneda(Constantes.CONSTANTE_TIPO_MONEDA_EUR);
		lista.add(posiActual);
		posiActual=new PosicionRebalanceoTO();
		posiActual.setMoneda(Constantes.CONSTANTE_TIPO_MONEDA_USD);
		lista.add(posiActual);
		return lista;
	}
	
	public HashMap<String, String> addRow(String ... campo){
		HashMap<String, String> fila= new HashMap<String, String>();
		fila.put("idcategoriaporproducto",campo[0]);
		fila.put("idcategoriaactivo",campo[1]);
		fila.put("codproducto",campo[2]);
		fila.put("codsubproducto",campo[3]);
		fila.put("descripcion",campo[4]);
		fila.put("descripciontotal",campo[5]);
		fila.put("descripcionplazo",campo[6]);
		fila.put("moneda",campo[7]);
		fila.put("saldoactual",campo[8]);
		fila.put("saldoretenido",campo[9]);
		fila.put("indretencion",campo[11]);
		fila.put("peso",campo[12]);		
		return fila;
	}

	public List<Map<String, Object>> listarDistribucionCategoriaActivos(String codCliente,String codContratos,String codRegistro) {		
		List<Map<String, Object>> lista=calculadoraModDAOIface.listarDistribucionCategoriaActivos(codCliente,codContratos,codRegistro);
		Map<String, Object> itemRecursos=new HashMap<String, Object>();		
		itemRecursos.put("idcategoriaactivo",Constantes.ID_CATEGORIA_ACTIVO_RECURSOS);
		itemRecursos.put("descripcioncatactivo","NUEVOS RECURSOS");
		itemRecursos.put("saldoactualpenmo","");
		itemRecursos.put("saldoactualusdmo","");
		itemRecursos.put("saldoactualeurmo","");
		itemRecursos.put("pesoactual","");
		itemRecursos.put("pesoideal","");
		itemRecursos.put("desviacionporcentualusd","");
		itemRecursos.put("sugerido","");
		lista.add(itemRecursos);
		return lista;
	}
	
	public void procesarPosicionActual(String monedaSeleccionada,List<PosicionRebalanceoTO> listaPosicionActual,PosicionRebalanceoTO totalPosicionActual,List<Map<String, Object>> listaCalculadora,List<Map<String, Object>> listaRecursos){
		BigDecimal totalSaldoPEN= new BigDecimal(0);
		BigDecimal totalSaldoUSD= new BigDecimal(0);
		BigDecimal totalSaldoEUR= new BigDecimal(0);		
		BigDecimal totalRentabilidadPEN= new BigDecimal(0);
		BigDecimal totalRentabilidadUSD= new BigDecimal(0);
		BigDecimal totalRentabilidadEUR= new BigDecimal(0);		
		BigDecimal totalSaldoPENDolarizado= new BigDecimal(0);
		BigDecimal totalSaldoUSDDolarizado= new BigDecimal(0);
		BigDecimal totalSaldoEURDolarizado= new BigDecimal(0);		
		BigDecimal totalProdRentaPEN= new BigDecimal(0);
		BigDecimal totalProdRentaUSD= new BigDecimal(0);
		BigDecimal totalProdRentaEUR= new BigDecimal(0);
		
		for(Map<String, Object> subLista:listaCalculadora){
			List<RebalanceoTO> listaDetalle=(List<RebalanceoTO>)subLista.get("detalle");			
			for(RebalanceoTO filaSubLista:listaDetalle){
				if(filaSubLista.getMoneda().equals(Constantes.CONSTANTE_TIPO_MONEDA_EUR)){
					totalSaldoEUR=totalSaldoEUR.add(Util.big(filaSubLista.getSaldoActual()));
					totalRentabilidadEUR=totalRentabilidadEUR.add(Util.big(filaSubLista.getRentabilidad()));
					totalSaldoEURDolarizado=totalSaldoEURDolarizado.add(filaSubLista.getSaldoActualDolarizado());
					totalProdRentaEUR=totalProdRentaEUR.add(Util.fixMultiply(Util.big(filaSubLista.getSaldoActual()), Util.big(filaSubLista.getRentabilidad())));
				}else if(filaSubLista.getMoneda().equals(Constantes.CONSTANTE_TIPO_MONEDA_USD)){
					totalSaldoUSD=totalSaldoUSD.add(Util.big(filaSubLista.getSaldoActual()));
					totalRentabilidadUSD=totalRentabilidadUSD.add(Util.big(filaSubLista.getRentabilidad()));
					totalSaldoUSDDolarizado=totalSaldoUSDDolarizado.add(filaSubLista.getSaldoActualDolarizado());
					totalProdRentaUSD=totalProdRentaUSD.add(Util.fixMultiply(Util.big(filaSubLista.getSaldoActual()), Util.big(filaSubLista.getRentabilidad())));
				}else if(filaSubLista.getMoneda().equals(Constantes.CONSTANTE_TIPO_MONEDA_PEN)){
					totalSaldoPEN=totalSaldoPEN.add(Util.big(filaSubLista.getSaldoActual()));
					totalRentabilidadPEN=totalRentabilidadPEN.add(Util.big(filaSubLista.getRentabilidad()));
					totalSaldoPENDolarizado=totalSaldoPENDolarizado.add(filaSubLista.getSaldoActualDolarizado());
					totalProdRentaPEN=totalProdRentaPEN.add(Util.fixMultiply(Util.big(filaSubLista.getSaldoActual()), Util.big(filaSubLista.getRentabilidad())));
				}
			}
		}
		
		for(Map<String, Object> subLista:listaRecursos){
			List<RebalanceoTO> listaDetalle=(List<RebalanceoTO>)subLista.get("detalle");			
			for(RebalanceoTO filaSubLista:listaDetalle){
				if(filaSubLista.getMoneda().equals(Constantes.CONSTANTE_TIPO_MONEDA_EUR)){
					totalSaldoEUR=totalSaldoEUR.add(Util.big(filaSubLista.getSaldoActual()));
					totalSaldoEURDolarizado=totalSaldoEURDolarizado.add(filaSubLista.getSaldoActualDolarizado());
				}else if(filaSubLista.getMoneda().equals(Constantes.CONSTANTE_TIPO_MONEDA_USD)){
					totalSaldoUSD=totalSaldoUSD.add(Util.big(filaSubLista.getSaldoActual()));
					totalSaldoUSDDolarizado=totalSaldoUSDDolarizado.add(filaSubLista.getSaldoActualDolarizado());
				}else if(filaSubLista.getMoneda().equals(Constantes.CONSTANTE_TIPO_MONEDA_PEN)){
					totalSaldoPEN=totalSaldoPEN.add(Util.big(filaSubLista.getSaldoActual()));
					totalSaldoPENDolarizado=totalSaldoPENDolarizado.add(filaSubLista.getSaldoActualDolarizado());
				}
			}
		}
		
		cargarTablaPosicion( monedaSeleccionada,listaPosicionActual,totalPosicionActual,totalSaldoEURDolarizado,
							 totalSaldoUSDDolarizado,totalSaldoPENDolarizado,totalSaldoEUR,totalProdRentaEUR,totalRentabilidadEUR,
							 totalSaldoUSD,totalProdRentaUSD,totalRentabilidadUSD,totalSaldoPEN,totalProdRentaPEN,totalRentabilidadPEN);
		
	}
	
	public void procesarPosicionSugerida(String monedaSeleccionada,List<PosicionRebalanceoTO> listaPosicionSugerida,PosicionRebalanceoTO totalPosicionSugerida,List<Map<String, Object>> listaCalculadora){
		BigDecimal totalSaldoPEN= new BigDecimal(0);
		BigDecimal totalSaldoUSD= new BigDecimal(0);
		BigDecimal totalSaldoEUR= new BigDecimal(0);		
		BigDecimal totalRentabilidadPEN= new BigDecimal(0);
		BigDecimal totalRentabilidadUSD= new BigDecimal(0);
		BigDecimal totalRentabilidadEUR= new BigDecimal(0);		
		BigDecimal totalSaldoPENDolarizado= new BigDecimal(0);
		BigDecimal totalSaldoUSDDolarizado= new BigDecimal(0);
		BigDecimal totalSaldoEURDolarizado= new BigDecimal(0);		
		BigDecimal totalProdRentaPEN= new BigDecimal(0);
		BigDecimal totalProdRentaUSD= new BigDecimal(0);
		BigDecimal totalProdRentaEUR= new BigDecimal(0);
		
		for(Map<String, Object> subLista:listaCalculadora){
			List<RebalanceoTO> listaDetalle=(List<RebalanceoTO>)subLista.get("detalle");			
			for(RebalanceoTO filaSubLista:listaDetalle){
				if(filaSubLista.getMoneda().equals(Constantes.CONSTANTE_TIPO_MONEDA_EUR)){
					totalSaldoEUR=totalSaldoEUR.add(filaSubLista.getSaldoResultante());
					totalRentabilidadEUR=totalRentabilidadEUR.add(Util.big(filaSubLista.getRentabilidadEstimada()));
					totalSaldoEURDolarizado=totalSaldoEURDolarizado.add(Util.big(filaSubLista.getSaldoResultanteDolarizado()));
					totalProdRentaEUR=totalProdRentaEUR.add(Util.fixMultiply(filaSubLista.getSaldoResultante(), Util.big(filaSubLista.getRentabilidadEstimada())));
				}else if(filaSubLista.getMoneda().equals(Constantes.CONSTANTE_TIPO_MONEDA_USD)){
					totalSaldoUSD=totalSaldoUSD.add(filaSubLista.getSaldoResultante());
					totalRentabilidadUSD=totalRentabilidadUSD.add(Util.big(filaSubLista.getRentabilidadEstimada()));
					totalSaldoUSDDolarizado=totalSaldoUSDDolarizado.add(Util.big(filaSubLista.getSaldoResultanteDolarizado()));
					totalProdRentaUSD=totalProdRentaUSD.add(Util.fixMultiply(filaSubLista.getSaldoResultante(), Util.big(filaSubLista.getRentabilidadEstimada())));
				}else if(filaSubLista.getMoneda().equals(Constantes.CONSTANTE_TIPO_MONEDA_PEN)){
					totalSaldoPEN=totalSaldoPEN.add(filaSubLista.getSaldoResultante());
					totalRentabilidadPEN=totalRentabilidadPEN.add(Util.big(filaSubLista.getRentabilidadEstimada()));
					totalSaldoPENDolarizado=totalSaldoPENDolarizado.add(Util.big(filaSubLista.getSaldoResultanteDolarizado()));
					totalProdRentaPEN=totalProdRentaPEN.add(Util.fixMultiply(filaSubLista.getSaldoResultante(), Util.big(filaSubLista.getRentabilidadEstimada())));
				}
			}
		}		
		cargarTablaPosicion( monedaSeleccionada,listaPosicionSugerida,totalPosicionSugerida,totalSaldoEURDolarizado,
							 totalSaldoUSDDolarizado,totalSaldoPENDolarizado,totalSaldoEUR,totalProdRentaEUR,totalRentabilidadEUR,
							 totalSaldoUSD,totalProdRentaUSD,totalRentabilidadUSD,totalSaldoPEN,totalProdRentaPEN,totalRentabilidadPEN);
	}
	
	public void cargarTablaPosicion(String monedaSeleccionada,									
									List<PosicionRebalanceoTO> listaPosicionActual,
									PosicionRebalanceoTO totalPosicionActual,
									BigDecimal totalSaldoEURDolarizado,
									BigDecimal totalSaldoUSDDolarizado,
									BigDecimal totalSaldoPENDolarizado,
									BigDecimal totalSaldoEUR,
									BigDecimal totalProdRentaEUR,
									BigDecimal totalRentabilidadEUR,
									BigDecimal totalSaldoUSD,
									BigDecimal totalProdRentaUSD,
									BigDecimal totalRentabilidadUSD,
									BigDecimal totalSaldoPEN,
									BigDecimal totalProdRentaPEN,
									BigDecimal totalRentabilidadPEN){
		BigDecimal totalActualPeso=new BigDecimal("0");
		BigDecimal totalActualRenta=new BigDecimal("0");
		BigDecimal totalActualRendimiento=new BigDecimal("0");
		for(PosicionRebalanceoTO fila:listaPosicionActual){
			BigDecimal total=Util.nvlDivisor(totalSaldoEURDolarizado.add(totalSaldoUSDDolarizado).add(totalSaldoPENDolarizado));
			if(fila.getMoneda().equals(Constantes.CONSTANTE_TIPO_MONEDA_EUR)){
				fila.setTotalInversion(totalSaldoEUR);
				fila.setPeso(Util.fixMultiply(totalSaldoEURDolarizado, Util.big("100")).divide(total,2,RoundingMode.HALF_UP));
				fila.setRentabilidad(totalProdRentaEUR.divide(Util.nvlDivisor(totalSaldoEUR),4,RoundingMode.HALF_UP));
				fila.setRendimientoEstimado(Util.fixMultiply(fila.getTotalInversion(), fila.getRentabilidad()).divide(big("100")));
			}else if(fila.getMoneda().equals(Constantes.CONSTANTE_TIPO_MONEDA_USD)){
				fila.setTotalInversion(totalSaldoUSD);
				fila.setPeso(Util.fixMultiply(totalSaldoUSDDolarizado, Util.big("100")).divide(total,2,RoundingMode.HALF_UP));
				fila.setRentabilidad(totalProdRentaUSD.divide(Util.nvlDivisor(totalSaldoUSD),4,RoundingMode.HALF_UP));
				fila.setRendimientoEstimado(Util.fixMultiply(fila.getTotalInversion(), fila.getRentabilidad()).divide(big("100")));
			}else if(fila.getMoneda().equals(Constantes.CONSTANTE_TIPO_MONEDA_PEN)){
				fila.setTotalInversion(totalSaldoPEN);
				fila.setPeso(Util.fixMultiply(totalSaldoPENDolarizado, Util.big("100")).divide(total,2,RoundingMode.HALF_UP));
				fila.setRentabilidad(totalProdRentaPEN.divide(Util.nvlDivisor(totalSaldoPEN),4,RoundingMode.HALF_UP));
				fila.setRendimientoEstimado(Util.fixMultiply(fila.getTotalInversion(), fila.getRentabilidad()).divide(big("100")));
			}
			//calcular totales//
			totalActualPeso=totalActualPeso.add(fila.getPeso());
			//*****************************************************
			totalActualRenta=totalActualRenta.add((Util.fixMultiply(fila.getRentabilidad(), fila.getPeso())).divide(big("100"),2,RoundingMode.HALF_UP));
			//*****************************************************
			totalActualRendimiento=totalActualRendimiento.add(fila.getRendimientoEstimado());
		}
		FactorTipoCambio ftc=calculadoraModDAOIface.ObtenerFactorTipoCambio();
		//***ojo
		BigDecimal sipen=Util.fixMultiply(ftc.factorTipoCambio(Constantes.CONSTANTE_TIPO_MONEDA_PEN,monedaSeleccionada), totalSaldoPEN);
		BigDecimal siusd=Util.fixMultiply(ftc.factorTipoCambio(Constantes.CONSTANTE_TIPO_MONEDA_USD,monedaSeleccionada), totalSaldoUSD);
		BigDecimal sieur=Util.fixMultiply(ftc.factorTipoCambio(Constantes.CONSTANTE_TIPO_MONEDA_EUR,monedaSeleccionada), totalSaldoEUR);
		//********************************
		
		totalPosicionActual.setTotalInversion(sipen.add(siusd).add(sieur));
		
		totalPosicionActual.setRentabilidad(totalActualRenta);
		totalPosicionActual.setPeso(totalActualPeso);
		
		totalPosicionActual.setRendimientoEstimado(Util.fixMultiply(totalPosicionActual.getRentabilidad(), totalPosicionActual.getTotalInversion()).divide(big("100")));
	}
	
	@SuppressWarnings("unchecked")
	public List<Map<String, Object>> procesar(String monedaActual,List<Map<String, Object>> listaCalculadora,RebalanceoTO totalCalculadora){
		
		FactorTipoCambio ftc=calculadoraModDAOIface.ObtenerFactorTipoCambio();
		RebalanceoTO pie;
		BigDecimal totalSaldoResultante;
		BigDecimal totalSaldoActual;
		BigDecimal totalSaldoActualTotal=new BigDecimal(0);
		BigDecimal totalSaldoResultanteTotal=new BigDecimal(0);
		
		BigDecimal totalSubRentabilidadActual=new BigDecimal(0);
		BigDecimal totalSubRentabilidadEstimada=new BigDecimal(0);
		
		for(Map<String, Object> subLista:listaCalculadora){
			List<RebalanceoTO> listaDetalle=(List<RebalanceoTO>)subLista.get("detalle");
			BigDecimal totalSaldoResultante1=new BigDecimal(0);
			BigDecimal totalSaldoActual1=new BigDecimal(0);
			BigDecimal sumatoriaTemp= new BigDecimal(0);
			for(RebalanceoTO filaSubLista:listaDetalle){
				sumatoriaTemp= new BigDecimal(0);
				BigDecimal sipen=Util.fixMultiply(ftc.factorTipoCambio(Constantes.CONSTANTE_TIPO_MONEDA_PEN,filaSubLista.getMoneda()), big(filaSubLista.getSaldoInputPEN()));
				BigDecimal siusd=Util.fixMultiply(ftc.factorTipoCambio(Constantes.CONSTANTE_TIPO_MONEDA_USD,filaSubLista.getMoneda()), big(filaSubLista.getSaldoInputUSD()));
				BigDecimal sieur=Util.fixMultiply(ftc.factorTipoCambio(Constantes.CONSTANTE_TIPO_MONEDA_EUR,filaSubLista.getMoneda()), big(filaSubLista.getSaldoInputEUR()));				
				BigDecimal factorSaldoResultanteTotal=ftc.factorTipoCambio(filaSubLista.getMoneda(),monedaActual);
				
				sumatoriaTemp = sumatoriaTemp.add(big(filaSubLista.getSaldoActual()));
				sumatoriaTemp = sumatoriaTemp.add(sipen);
				sumatoriaTemp = sumatoriaTemp.add(siusd);
				sumatoriaTemp = sumatoriaTemp.add(sieur);
				
				totalSaldoResultante1=totalSaldoResultante1.add(Util.fixMultiply(sumatoriaTemp, factorSaldoResultanteTotal));
				totalSaldoActual1=totalSaldoActual1.add(Util.fixMultiply(big(filaSubLista.getSaldoActual()), factorSaldoResultanteTotal));				
			}
			
			totalSaldoActualTotal=totalSaldoActualTotal.add(totalSaldoActual1);
			totalSaldoResultanteTotal=totalSaldoResultanteTotal.add(totalSaldoResultante1);
		}
		for(Map<String, Object> subLista:listaCalculadora){
			List<RebalanceoTO> listaDetalle=(List<RebalanceoTO>)subLista.get("detalle");
			totalSaldoResultante=new BigDecimal(0);
			totalSaldoActual=new BigDecimal(0);
			totalSubRentabilidadActual=new BigDecimal(0);
			totalSubRentabilidadEstimada=new BigDecimal(0);
			for(RebalanceoTO filaSubLista:listaDetalle){
				
				BigDecimal sipen=Util.fixMultiply(ftc.factorTipoCambio(Constantes.CONSTANTE_TIPO_MONEDA_PEN,filaSubLista.getMoneda()), big(filaSubLista.getSaldoInputPEN()));
				BigDecimal siusd=Util.fixMultiply(ftc.factorTipoCambio(Constantes.CONSTANTE_TIPO_MONEDA_USD,filaSubLista.getMoneda()), big(filaSubLista.getSaldoInputUSD()));
				BigDecimal sieur=Util.fixMultiply(ftc.factorTipoCambio(Constantes.CONSTANTE_TIPO_MONEDA_EUR,filaSubLista.getMoneda()), big(filaSubLista.getSaldoInputEUR()));				
				
				filaSubLista.setSaldoResultante(big(filaSubLista.getSaldoActual()).add(sipen).add(siusd).add(sieur));
				filaSubLista.setSaldoResultanteDolarizado(Util.fixMultiply(ftc.factorTipoCambio(filaSubLista.getMoneda(),monedaActual), filaSubLista.getSaldoResultante()).toString());
				filaSubLista.setSaldoActualDolarizado(Util.fixMultiply(big(filaSubLista.getSaldoActual()), ftc.factorTipoCambio(filaSubLista.getMoneda(),monedaActual)));
				
				BigDecimal factorSaldoResultanteTotal=ftc.factorTipoCambio(filaSubLista.getMoneda(),monedaActual);
				
				totalSaldoResultante=totalSaldoResultante.add(Util.fixMultiply(filaSubLista.getSaldoResultante(), factorSaldoResultanteTotal));
				totalSaldoActual=totalSaldoActual.add(Util.fixMultiply(big(filaSubLista.getSaldoActual()), factorSaldoResultanteTotal));
			}
			
			//calculando el pie de la sublista
			pie=(RebalanceoTO)subLista.get("pie");			
			pie.setSaldoActual(String.valueOf(totalSaldoActual));
			pie.setSaldoResultante(totalSaldoResultante);	

			//calculando pesos
			for(RebalanceoTO filaSubLista:listaDetalle){
				BigDecimal pesoFamiliaTemp= new BigDecimal(0);
				BigDecimal pesoTemp= new BigDecimal(0);
				try{
					BigDecimal factorSaldoResultanteTotal=ftc.factorTipoCambio(filaSubLista.getMoneda(),monedaActual);
					pesoFamiliaTemp = (Util.fixMultiply(filaSubLista.getSaldoResultante(), factorSaldoResultanteTotal)).divide(totalSaldoResultanteTotal,2,RoundingMode.HALF_UP);
					filaSubLista.setPesoFamilia(Util.fixMultiply(pesoFamiliaTemp, big("100")));
					
				}catch(ArithmeticException e){
					filaSubLista.setPesoFamilia(big("0"));
				}
				
				//***OJO
				try{
					BigDecimal factorSaldoResultanteTotal=ftc.factorTipoCambio(filaSubLista.getMoneda(),monedaActual);
					pesoTemp = (Util.fixMultiply(big(filaSubLista.getSaldoActual()), factorSaldoResultanteTotal)).divide(totalSaldoActualTotal,2,RoundingMode.HALF_UP);
					filaSubLista.setPeso(Util.fixMultiply(pesoTemp, big("100")));
				}catch(ArithmeticException e){
					filaSubLista.setPeso(big("0"));
				}
				
				totalSubRentabilidadActual=totalSubRentabilidadActual.add(Util.fixMultiply(filaSubLista.getPeso(), big(filaSubLista.getRentabilidad())).divide(big("100")));
				totalSubRentabilidadEstimada=totalSubRentabilidadEstimada.add(Util.fixMultiply(filaSubLista.getPesoFamilia(), big(filaSubLista.getRentabilidadEstimada())).divide(big("100")));
			
			}
			pie.setRentabilidad(String.valueOf(totalSubRentabilidadActual));
			pie.setRentabilidadEstimada(String.valueOf(totalSubRentabilidadEstimada));
			
		}				
		//calculando peso de totales
		totalCalculadora.setSaldoActual(new BigDecimal(0).toString());
		totalCalculadora.setSaldoResultante(new BigDecimal(0));
		totalCalculadora.setPeso(new BigDecimal(0));
		totalCalculadora.setPesoFamilia(new BigDecimal(0));
		for(Map<String, Object> subLista:listaCalculadora){
			pie=(RebalanceoTO)subLista.get("pie");
			
			try{
				pie.setPeso(Util.fixMultiply(Util.big(pie.getSaldoActual()), big("100")).divide(Util.nvlDivisor(totalSaldoActualTotal),2,RoundingMode.HALF_UP));
			}catch(ArithmeticException e){
				pie.setPeso(big("0"));
			}
			try{
				pie.setPesoFamilia(Util.fixMultiply(pie.getSaldoResultante(), big("100")).divide(Util.nvlDivisor(totalSaldoResultanteTotal),2,RoundingMode.HALF_UP));
			}catch(ArithmeticException e){
				pie.setPesoFamilia(big("0"));
			}
			
			totalCalculadora.setSaldoActual(String.valueOf(big(pie.getSaldoActual()).add(big(totalCalculadora.getSaldoActual()))));
			totalCalculadora.setSaldoResultante(pie.getSaldoResultante().add(totalCalculadora.getSaldoResultante()));
			totalCalculadora.setPeso(pie.getPeso().add(totalCalculadora.getPeso()));
			totalCalculadora.setPesoFamilia(pie.getPesoFamilia().add(totalCalculadora.getPesoFamilia()));
		}		
		
		return listaCalculadora;
	}
	
	public List<Map<String,Object>> procesarPerfilInversor(String idCatActivo,String codProducto,String codSubproducto,String monto,String moneda){		
		return calculadoraModDAOIface.calculoPropuesta(idCatActivo, codProducto, codSubproducto, monto, moneda);
	}
	
	@SuppressWarnings("unchecked")
	public List<Map<String, Object>> procesarRecursos(String monedaActual,List<Map<String, Object>> listaCalculadora,RebalanceoTO totalRecursos){
		
		FactorTipoCambio ftc=calculadoraModDAOIface.ObtenerFactorTipoCambio();		
		RebalanceoTO pie;
		BigDecimal totalSaldoResultante;
		BigDecimal totalSaldoActual;
		for(Map<String, Object> subLista:listaCalculadora){
			List<RebalanceoTO> listaDetalle=(List<RebalanceoTO>)subLista.get("detalle");
			totalSaldoResultante=new BigDecimal(0);
			totalSaldoActual=new BigDecimal(0);
			for(RebalanceoTO filaSubLista:listaDetalle){
				BigDecimal sp=new BigDecimal(0);
				if(filaSubLista.getMoneda().equals(Constantes.CONSTANTE_TIPO_MONEDA_PEN)){
					sp= big(filaSubLista.getSaldoInputPEN());					
				}else if(filaSubLista.getMoneda().equals(Constantes.CONSTANTE_TIPO_MONEDA_USD)){
					sp=big(filaSubLista.getSaldoInputUSD());					
				}else if(filaSubLista.getMoneda().equals(Constantes.CONSTANTE_TIPO_MONEDA_EUR)){
					sp=big(filaSubLista.getSaldoInputEUR());					
				}
				
				filaSubLista.setSaldoActualDolarizado(Util.fixMultiply(big(filaSubLista.getSaldoActual()), ftc.factorTipoCambio(filaSubLista.getMoneda(),monedaActual)));
				filaSubLista.setSaldoResultante(big(filaSubLista.getSaldoActual()).add(sp));
				BigDecimal factorSaldoResultanteTotal=ftc.factorTipoCambio(filaSubLista.getMoneda(),monedaActual);
				filaSubLista.setPeso(Util.fixMultiply(big(filaSubLista.getSaldoActual()), factorSaldoResultanteTotal));
				totalSaldoActual=totalSaldoActual.add(Util.fixMultiply(big(filaSubLista.getSaldoActual()), factorSaldoResultanteTotal));
				totalSaldoResultante=totalSaldoResultante.add(Util.fixMultiply(filaSubLista.getSaldoResultante(), factorSaldoResultanteTotal));
			}
			
			//modificando el pie de la sublista
			pie=(RebalanceoTO)subLista.get("pie");			
			pie.setSaldoActualDolarizado(totalSaldoActual);
			pie.setSaldoResultante(totalSaldoResultante);			
			
			//modificando pesos
			for(RebalanceoTO filaSubLista:listaDetalle){
				try{
					filaSubLista.setPeso(Util.fixMultiply(filaSubLista.getSaldoActualDolarizado(), big("100")).divide(totalSaldoActual,4,RoundingMode.HALF_UP));
				}catch(ArithmeticException e){
					filaSubLista.setPeso(big("0"));
				}
			}
		}	
		totalRecursos.setSaldoActual(new BigDecimal("0").toString());
		totalRecursos.setSaldoResultante(new BigDecimal("0"));
		totalRecursos.setSaldoActualDolarizado(new BigDecimal("0"));
		totalRecursos.setPeso(new BigDecimal("0"));
		totalRecursos.setSaldoResultante(new BigDecimal("0"));
		
		
		//llenado de totales
		for(Map<String, Object> subLista:listaCalculadora){
			pie=(RebalanceoTO)subLista.get("pie");
						
			totalRecursos.setSaldoActual(big(pie.getSaldoActual()).add(big(totalRecursos.getSaldoActual())).toString());
			totalRecursos.setSaldoResultante(pie.getSaldoResultante().add(totalRecursos.getSaldoResultante()));
			totalRecursos.setSaldoActualDolarizado(pie.getSaldoActualDolarizado().add(totalRecursos.getSaldoActualDolarizado()));
			totalRecursos.setPeso(pie.getPeso().add(totalRecursos.getPeso()));			
		}	
		
		for(Map<String, Object> subLista:listaCalculadora){
			pie=(RebalanceoTO)subLista.get("pie");
			try{
				pie.setPeso(Util.fixMultiply(pie.getSaldoActualDolarizado(), big("100")).divide(totalRecursos.getSaldoActualDolarizado(),2,RoundingMode.HALF_UP));
			}catch(ArithmeticException e){
				pie.setPeso(big("0"));
			}
		}
		
		return listaCalculadora;
	}
	
	public BigDecimal big(String valor){
		return Util.big(valor);
	}

	public List<Map<String, Object>> listarDistribucionRecursos() {
		int i=0;
		List<Map<String,Object>> listaDistribucion=calculadoraModDAOIface.listarCalculadoraRecursos();//listarDistribucionRecursosProcedimiento();
		List<Map<String, Object>> listaPadre=new ArrayList<Map<String,Object>>();		
		if(listaDistribucion.size()>0){
			List<RebalanceoTO> sublista=new ArrayList<RebalanceoTO>();
			RebalanceoTO reba=new RebalanceoTO();
			RebalanceoTO pie=new RebalanceoTO();
			String idCatProducto=String.valueOf(listaDistribucion.get(0).get("idcategoriaporproducto"));		
			for(Map<String, Object> x:listaDistribucion){
				if(!x.get("idcategoriaporproducto").equals(idCatProducto)){
					idCatProducto=String.valueOf(x.get("idcategoriaporproducto"));
					//agregar pie
					Map<String,Object> item=new HashMap<String, Object>();
					item.put("detalle", sublista);
					item.put("pie", pie);
					listaPadre.add(item);
					sublista=new ArrayList<RebalanceoTO>();
					pie=new RebalanceoTO();
				}
				reba=new RebalanceoTO();
				//reba.setFila(i++);
				reba.setDescripcion(String.valueOf(x.get("descripcion")));
			
				reba.setMoneda(String.valueOf(x.get("moneda")));				
				reba.setCodCatProd(String.valueOf(x.get("idcategoriaporproducto")));
				reba.setCodCatActivo(String.valueOf(x.get("idcategoriaactivo")));
			
				sublista.add(reba);				
				pie.setDescripcion(String.valueOf(x.get("descripciontotal")));								
			}
			Map<String,Object> item=new HashMap<String, Object>();
			item.put("detalle", sublista);
			item.put("pie", pie);
			listaPadre.add(item);
		}	
		return listaPadre;
	}
	
	public List<Map<String, Object>> listarDistribucionRecursosModificar() {
		int i=0;
		List<Map<String,Object>> listaDistribucion=calculadoraModDAOIface.listarCalculadoraRecursos();//listarDistribucionRecursosProcedimiento();
		List<Map<String, Object>> listaPadre=new ArrayList<Map<String,Object>>();		
		if(listaDistribucion.size()>0){
			List<RebalanceoTO> sublista=new ArrayList<RebalanceoTO>();
			RebalanceoTO reba=new RebalanceoTO();
			RebalanceoTO pie=new RebalanceoTO();
			String idCatProducto=String.valueOf(listaDistribucion.get(0).get("idcategoriaporproducto"));		
			for(Map<String, Object> x:listaDistribucion){
				if(!x.get("idcategoriaporproducto").equals(idCatProducto)){
					idCatProducto=String.valueOf(x.get("idcategoriaporproducto"));
					//agregar pie
					Map<String,Object> item=new HashMap<String, Object>();
					item.put("detalle", sublista);
					item.put("pie", pie);
					listaPadre.add(item);
					sublista=new ArrayList<RebalanceoTO>();
					pie=new RebalanceoTO();
				}
				reba=new RebalanceoTO();
				//reba.setFila(i++);
				reba.setDescripcion(String.valueOf(x.get("descripcion")));
			
				reba.setMoneda(String.valueOf(x.get("moneda")));				
				reba.setCodCatProd(String.valueOf(x.get("idcategoriaporproducto")));
				reba.setCodCatActivo(String.valueOf(x.get("idcategoriaactivo")));
				
				if(listaDistribucionCalEdion!=null && listaDistribucionCalEdion.size()>0){
					for(Map<String, Object> y:listaDistribucionCalEdion){
						if(y.get("idcategoriaactivo")!=null && y.get("idcategoriaproducto")!=null && y.get("moneda")!=null){
							if(reba.getCodCatActivo().trim().equals(Util.nvl(y.get("idcategoriaactivo")).toString().trim())&& 
									reba.getCodCatProd().trim().equals(Util.nvl(y.get("idcategoriaproducto").toString().trim()))&&
									reba.getMoneda().trim().equals(Util.nvl(y.get("moneda").toString().trim()))&&
									"R".equals(Util.nvl(y.get("tipo").toString().trim()))){
								        reba.setSaldoActual(Util.nvl(y.get("saldoactual")).toString());
								        
								        if (!Util.nvlNumber(y.get("calculadorapen")).toString().equalsIgnoreCase("0"))
								        {
								        	reba.setSaldoInputPEN(Util.nvl(y.get("calculadorapen")).toString());
								        }
								        
								        if (!Util.nvlNumber(y.get("calculadorausd")).toString().equalsIgnoreCase("0"))
								        {
								        	reba.setSaldoInputUSD(Util.nvl(y.get("calculadorausd")).toString());
								        }
								        
								        if (!Util.nvlNumber(y.get("calculadoraeur")).toString().equalsIgnoreCase("0"))
								        {
								        	reba.setSaldoInputEUR(Util.nvl(y.get("calculadoraeur")).toString());
								        }
								        
										reba.setIdrebalanceo(this.idrebalanceo);
										reba.setIdrebalanceodetalle(Util.nvl(y.get("idrebalanceodetalle")).toString());
							}
						}

					}
				}
				
				sublista.add(reba);				
				pie.setDescripcion(String.valueOf(x.get("descripciontotal")));								
			}
			Map<String,Object> item=new HashMap<String, Object>();
			item.put("detalle", sublista);
			item.put("pie", pie);
			listaPadre.add(item);
		}	
		return listaPadre;
	}
	
	public List<Map<String,Object>> retornaDesviacionPropuesta(String categoriaActivos,String valores){
		try {
			return calculadoraDaoIface.retornaDesviacionPropuesta(categoriaActivos, valores);
		} catch (Exception e) { 
			e.printStackTrace();
		}	
		return new ArrayList<Map<String,Object>>();
	}
	
	private Map<String,StringBuilder> cargarDetalleRecursos(RebalanceoTO fila){
		StringBuilder fuenteDetalleRecursoTemp=new StringBuilder();
		StringBuilder procedenciaDetalleRecursoTemp=new StringBuilder();
		StringBuilder montoDetalleRecursoTemp=new StringBuilder();		
		
		for(MontoCalculadoraTO monto: fila.getListDetalleSaldos()){
			fuenteDetalleRecursoTemp.append(Constantes.CONSTANTE_SEPARADOR_SUB_ARRAY_STORE).append(monto.getFuente());
			procedenciaDetalleRecursoTemp.append(Constantes.CONSTANTE_SEPARADOR_SUB_ARRAY_STORE).append(monto.getProcedencia());
			montoDetalleRecursoTemp.append(Constantes.CONSTANTE_SEPARADOR_SUB_ARRAY_STORE).append(monto.getMonto());					
		}
		
		if(fila.getListDetalleSaldos().size()>0){
			fuenteDetalleRecursoTemp =new StringBuilder(fuenteDetalleRecursoTemp.substring(1));
			procedenciaDetalleRecursoTemp=new StringBuilder(procedenciaDetalleRecursoTemp.substring(1));
			montoDetalleRecursoTemp=new StringBuilder(montoDetalleRecursoTemp.substring(1));					
		}
		fuenteDetalleRecursoTemp=new StringBuilder(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fuenteDetalleRecursoTemp);
		procedenciaDetalleRecursoTemp=new StringBuilder(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(procedenciaDetalleRecursoTemp);
		montoDetalleRecursoTemp=new StringBuilder(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(montoDetalleRecursoTemp);
		
		Map<String,StringBuilder> map=new HashMap<String, StringBuilder>();
		map.put("fuenteDetalleRecursoTemp", fuenteDetalleRecursoTemp);
		map.put("procedenciaDetalleRecursoTemp", procedenciaDetalleRecursoTemp);
		map.put("montoDetalleRecursoTemp", montoDetalleRecursoTemp);
		return map;
	}
	
	
	private Map<String,StringBuilder> cargarDetalleDetalle(RebalanceoTO fila){
		StringBuilder monedaDetalleDetalleTemp=new StringBuilder();
		StringBuilder operacionDetalleTemp=new StringBuilder();
		StringBuilder montoDetalleDetalleTemp=new StringBuilder();
		
		BigDecimal total=calculaTotalModal(fila.getListDetalleMontosUSD());
		if(total.compareTo(Util.big(fila.getSaldoInputUSD()))!=0){
			fila.setListDetalleMontosUSD(cargarListaInput(fila.getSaldoInputUSD()));
		}
		for(MontoCalculadoraTO montoUSD: fila.getListDetalleMontosUSD()){
			monedaDetalleDetalleTemp.append(Constantes.CONSTANTE_SEPARADOR_SUB_ARRAY_STORE).append(Constantes.CONSTANTE_TIPO_MONEDA_USD);
			operacionDetalleTemp.append(Constantes.CONSTANTE_SEPARADOR_SUB_ARRAY_STORE).append(montoUSD.getOperacion());
			montoDetalleDetalleTemp.append(Constantes.CONSTANTE_SEPARADOR_SUB_ARRAY_STORE).append(montoUSD.getMonto());					
		}
		
		total=calculaTotalModal(fila.getListDetalleMontosEUR());
		if(total.compareTo(Util.big(fila.getSaldoInputEUR()))!=0){
			fila.setListDetalleMontosEUR(cargarListaInput(fila.getSaldoInputEUR()));
		}
		for(MontoCalculadoraTO montoEUR: fila.getListDetalleMontosEUR()){
			monedaDetalleDetalleTemp.append(Constantes.CONSTANTE_SEPARADOR_SUB_ARRAY_STORE).append(Constantes.CONSTANTE_TIPO_MONEDA_EUR);
			operacionDetalleTemp.append(Constantes.CONSTANTE_SEPARADOR_SUB_ARRAY_STORE).append(montoEUR.getOperacion());
			montoDetalleDetalleTemp.append(Constantes.CONSTANTE_SEPARADOR_SUB_ARRAY_STORE).append(montoEUR.getMonto());					
		}
		
		total=calculaTotalModal(fila.getListDetalleMontosPEN());
		if(total.compareTo(Util.big(fila.getSaldoInputPEN()))!=0){
			fila.setListDetalleMontosPEN(cargarListaInput(fila.getSaldoInputPEN()));
		}
		for(MontoCalculadoraTO montoPEN: fila.getListDetalleMontosPEN()){
			monedaDetalleDetalleTemp.append(Constantes.CONSTANTE_SEPARADOR_SUB_ARRAY_STORE).append(Constantes.CONSTANTE_TIPO_MONEDA_PEN);
			operacionDetalleTemp.append(Constantes.CONSTANTE_SEPARADOR_SUB_ARRAY_STORE).append(montoPEN.getOperacion());
			montoDetalleDetalleTemp.append(Constantes.CONSTANTE_SEPARADOR_SUB_ARRAY_STORE).append(montoPEN.getMonto());					
		}
		
		if(fila.getListDetalleMontosUSD().size()>0||fila.getListDetalleMontosEUR().size()>0||fila.getListDetalleMontosPEN().size()>0){
			monedaDetalleDetalleTemp =new StringBuilder(monedaDetalleDetalleTemp.substring(1));
			operacionDetalleTemp=new StringBuilder(operacionDetalleTemp.substring(1));
			montoDetalleDetalleTemp=new StringBuilder(montoDetalleDetalleTemp.substring(1));					
		}
		monedaDetalleDetalleTemp=new StringBuilder(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(monedaDetalleDetalleTemp);
		operacionDetalleTemp=new StringBuilder(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(operacionDetalleTemp);
		montoDetalleDetalleTemp=new StringBuilder(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(montoDetalleDetalleTemp);
		
		Map<String,StringBuilder> map=new HashMap<String, StringBuilder>();
		map.put("monedaDetalleDetalleTemp", monedaDetalleDetalleTemp);
		map.put("operacionDetalleTemp", operacionDetalleTemp);
		map.put("montoDetalleDetalleTemp", montoDetalleDetalleTemp);
		return map;
	}
	
	public void guardarCalculadora(List<Map<String,Object>> listaCalculadora,List<Map<String,Object>> listaCalculadoraRecursos,
			List<Map<String,Object>> listaDistribucionCatActivo ,String codCliente,String idUsuarioAsesor,String comentario,
			String nroContratos,String codUsuCrea,String terminal) throws Exception{
		StringBuilder tipo=new StringBuilder();
		StringBuilder idCategoriaActivo=new StringBuilder();
		StringBuilder idCategoriaProducto=new StringBuilder();
		StringBuilder codProducto=new StringBuilder();
		StringBuilder codSubProducto=new StringBuilder();
		StringBuilder descripcion=new StringBuilder();
		StringBuilder moneda=new StringBuilder();
		StringBuilder plazo=new StringBuilder();
		StringBuilder saldoActual=new StringBuilder();
		StringBuilder saldoRetenido=new StringBuilder();
		StringBuilder rentabilidad=new StringBuilder();
		StringBuilder calculadoraPEN=new StringBuilder();
		StringBuilder calculadoraUSD=new StringBuilder();
		StringBuilder calculadoraEUR=new StringBuilder();
		StringBuilder rentabilidadEstimada=new StringBuilder();
		
		StringBuilder monedaDetalleDetalle=new StringBuilder();
		StringBuilder operacionDetalleDetalle=new StringBuilder();
		StringBuilder montoDetalleDetalle=new StringBuilder();
		
		Map<String,StringBuilder> map;
		
		StringBuilder fuenteDetalleRecurso=new StringBuilder();
		StringBuilder procedenciaDetalleRecurso=new StringBuilder();
		StringBuilder montoDetalleRecurso=new StringBuilder();
		
		for(Map<String,Object> x:listaCalculadora){
			List<RebalanceoTO> subLista=(List<RebalanceoTO>)x.get("detalle");
			for(RebalanceoTO fila:subLista){				
				
				tipo.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(Constantes.CONSTANTE_CALCULADORA_TIPO_BBVA);				
				idCategoriaActivo.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.getCodCatActivo());
				idCategoriaProducto.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.getCodCatProd());
				codProducto.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.getCodProd());
				codSubProducto.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.getCodSubProd());
				descripcion.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.getDescripcion());
				moneda.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.getMoneda());
				plazo.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.getPlazo());
				saldoActual.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.getSaldoActual());
				saldoRetenido.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.getSaldoRentenido());
				rentabilidad.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(Util.RetornaDecimalSinComa(fila.getRentabilidad()));//abarrios extrae coma
				calculadoraPEN.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(Util.RetornaDecimalSinComa(fila.getSaldoInputPEN()));//abarrios extrae coma
				calculadoraUSD.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(Util.RetornaDecimalSinComa(fila.getSaldoInputUSD()));//abarrios extrae coma
				calculadoraEUR.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(Util.RetornaDecimalSinComa(fila.getSaldoInputEUR()));//abarrios extrae coma
				rentabilidadEstimada.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(Util.RetornaDecimalSinComa(fila.getRentabilidadEstimada()));//abarrios extrae coma
				
				map=cargarDetalleDetalle(fila);
				monedaDetalleDetalle.append(map.get("monedaDetalleDetalleTemp"));
				operacionDetalleDetalle.append(map.get("operacionDetalleTemp"));
				montoDetalleDetalle.append(map.get("montoDetalleDetalleTemp"));
				
				fuenteDetalleRecurso.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE);
				procedenciaDetalleRecurso.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE);
				montoDetalleRecurso.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE);
			}
		}
		
		for(Map<String,Object> x:listaCalculadoraRecursos){
			List<RebalanceoTO> subLista=(List<RebalanceoTO>)x.get("detalle");
			for(RebalanceoTO fila:subLista){
				tipo.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(Constantes.CONSTANTE_CALCULADORA_TIPO_RECURSOS);				
				idCategoriaActivo.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(Util.nvl(fila.getCodCatActivo()));
				idCategoriaProducto.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(Util.nvl(fila.getCodCatProd()));
				
				codProducto.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE);//.append(fila.getCodProd());
				codSubProducto.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE);//.append(fila.getCodSubProd());
				
				descripcion.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.getDescripcion());
				moneda.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.getMoneda());
				
				plazo.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE);//.append(fila.getPlazo());
				
				saldoActual.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(Util.nvl(fila.getSaldoActual()));
				
				saldoRetenido.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE);//.append(fila.getSaldoRentenido());
				rentabilidad.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE);//.append(fila.getRentabilidad());
				
				calculadoraPEN.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(Util.nvl(fila.getSaldoInputPEN()));
				calculadoraUSD.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(Util.nvl(fila.getSaldoInputUSD()));
				calculadoraEUR.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(Util.nvl(fila.getSaldoInputEUR()));
				
				rentabilidadEstimada.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE);//.append(fila.getRentabilidadEstimada());	
				
				map=cargarDetalleDetalle(fila);
				monedaDetalleDetalle.append(map.get("monedaDetalleDetalleTemp"));
				operacionDetalleDetalle.append(map.get("operacionDetalleTemp"));
				montoDetalleDetalle.append(map.get("montoDetalleDetalleTemp"));
				
				map=cargarDetalleRecursos(fila);
				fuenteDetalleRecurso.append(map.get("fuenteDetalleRecursoTemp"));
				procedenciaDetalleRecurso.append(map.get("fuenteDetalleRecursoTemp"));
				montoDetalleRecurso.append(map.get("montoDetalleRecursoTemp"));
			}
		}
		
		StringBuilder descripcionDistrib=new StringBuilder();
		StringBuilder saldoActualPENDistrib=new StringBuilder();
		StringBuilder saldoActualUSDDistrib=new StringBuilder();
		StringBuilder saldoActualEURDistrib=new StringBuilder();
		StringBuilder perfilActualDistrib=new StringBuilder();
		StringBuilder perfilIdealDistrib=new StringBuilder();
		StringBuilder perfilSugeridoDistrib=new StringBuilder();
		StringBuilder saldoSugeridoUSDDistrib=new StringBuilder();
		StringBuilder saldoSugeridoPENDistrib=new StringBuilder();
		StringBuilder saldoSugeridoEURDistrib=new StringBuilder();
		StringBuilder idCatActivoDistrib=new StringBuilder();
		for(Map<String,Object> fila:listaDistribucionCatActivo){
			descripcionDistrib.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.get("descripcioncatactivo"));
			saldoActualPENDistrib.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.get("saldoactualpenmo"));
			saldoActualUSDDistrib.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.get("saldoactualusdmo"));
			saldoActualEURDistrib.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.get("saldoactualeurmo"));
			perfilActualDistrib.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.get("pesoactual"));
			perfilIdealDistrib.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.get("pesoideal"));
			perfilSugeridoDistrib.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.get("sugerido"));
			
			
			saldoSugeridoUSDDistrib.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.get("montoSugeridousd"));
			saldoSugeridoPENDistrib.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.get("montoSugeridopen"));
			saldoSugeridoEURDistrib.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.get("montoSugeridoeur"));			
			idCatActivoDistrib.append(Constantes.CONSTANTE_SEPARADOR_ARRAY_STORE).append(fila.get("idcategoriaactivo"));
		}
		
		String idRe;
		idRe=calculadoraModDAOIface.guardarCalculadora(codCliente,
												  idUsuarioAsesor,
												  comentario,
												  tipo.substring(1),
												  idCategoriaActivo.substring(1),
												  idCategoriaProducto.substring(1),
												  codProducto.substring(1),
												  codSubProducto.substring(1),
												  descripcion.substring(1),
												  moneda.substring(1),
												  plazo.substring(1),
												  saldoActual.substring(1),
												  saldoRetenido.substring(1),
												  rentabilidad.substring(1),
												  calculadoraPEN.substring(1),
												  calculadoraUSD.substring(1),
												  calculadoraEUR.substring(1),
												  rentabilidadEstimada.substring(1),
												  
												  descripcionDistrib.substring(1),
												  saldoActualPENDistrib.substring(1),
												  saldoActualUSDDistrib.substring(1),
												  saldoActualEURDistrib.substring(1),
												  perfilActualDistrib.substring(1),
												  perfilIdealDistrib.substring(1),
												  perfilSugeridoDistrib.substring(1),
												  saldoSugeridoUSDDistrib.substring(1),
												  saldoSugeridoPENDistrib.substring(1),
												  saldoSugeridoEURDistrib.substring(1),
												  idCatActivoDistrib.substring(1),
												  
												  monedaDetalleDetalle.substring(1),
												  operacionDetalleDetalle.substring(1),
												  montoDetalleDetalle.substring(1),
												  
												  fuenteDetalleRecurso.substring(1),
												  procedenciaDetalleRecurso.substring(1),
												  montoDetalleRecurso.substring(1),
												  
												  nroContratos,
												  codUsuCrea,
												  terminal
												  );
	}
	
	public FactorTipoCambio obtenerTipoCambio(){
		return calculadoraModDAOIface.ObtenerFactorTipoCambio();
	}
	
	public FactorTipoCambio obtenerTipoCambio(String fecha){
		return calculadoraModDAOIface.ObtenerFactorTipoCambio(fecha);
	}
	
	public ArrayList<MontoCalculadoraTO> cargarListaInput(String saldoInput){
		ArrayList<MontoCalculadoraTO> lista=new ArrayList<MontoCalculadoraTO>();		
		BigDecimal saldo=Util.big(saldoInput);
		if(saldo.intValue()!=0){
			MontoCalculadoraTO monto=new MontoCalculadoraTO();
			if(saldo.intValue()<0){
				monto.setOperacion(Constantes.SIGNO_NEGATIVO);
			}else{
				monto.setOperacion(Constantes.SIGNO_POSITIVO);
			}
			monto.setMonto(saldo.abs());							
			lista.add(monto);
		}		
		return lista;
	}
	
	private BigDecimal calculaTotalModal(List<MontoCalculadoraTO> lista){
		MontoCalculadoraTO totalModalMonto= new MontoCalculadoraTO();
		for(MontoCalculadoraTO fila:lista){
			if(fila.getOperacion().equals(Constantes.SIGNO_NEGATIVO)){
				totalModalMonto.setMonto(totalModalMonto.getMonto().add((fila.getMonto().negate())));
			}else{
				totalModalMonto.setMonto(totalModalMonto.getMonto().add(fila.getMonto()));
			}
		}
		return totalModalMonto.getMonto();				
	}
	/**
	 * @autor abarrios
	 * elimina los datos relacionados a un rebalanceo
	 */
	public void eliminaCalculadora(String idrebalanceo) throws Exception{
		calculadoraModDAOIface.eliminaCalculadora(idrebalanceo);
	}

	public List<Map<String, Object>> listarDistribucionCalcEdicionDetalle(String idrebalanceo, String idrebalanceoDet) {
		return calculadoraModDAOIface.listarDistribucionCalcEdicionDetalle(idrebalanceo, idrebalanceoDet);
	}
}
